package main

import (
	"encoding/binary"
	"fmt"
	"strings"
)

func parseParams(data []byte, stmt *preparedStatement) ([]interface{}, []byte, error) {
	params := []interface{}{}
	pos := 0 // 从数据的开始位置开始解析

	// 跳过 flags (1 byte)
	// pos += 1

	// 跳过 iteration count (4 bytes)，通常为 1
	pos += 4

	if pos >= len(data) {
		return nil, nil, fmt.Errorf("数据不足以解析参数")
	}

	// 计算 NULL bitmap 的长度
	nullBitmapLen := (stmt.params + 7) / 8
	if pos+nullBitmapLen > len(data) {
		return nil, nil, fmt.Errorf("数据不足以解析NULL bitmap")
	}

	nullBitmap := data[pos : pos+nullBitmapLen]
	pos += nullBitmapLen

	// 检查是否有新的参数绑定
	var newParamTypes []byte
	if pos < len(data) && data[pos] == 0x01 {
		pos++ // 跳过 new params bound flag
		if pos+stmt.params*2 > len(data) {
			return nil, nil, fmt.Errorf("数据不足以解析新的参数类型")
		}
		newParamTypes = data[pos : pos+stmt.params*2]
		pos += stmt.params * 2
	}

	// 如果没有新的参数类型，使用之前保存的类型
	paramTypes := newParamTypes
	if paramTypes == nil {
		paramTypes = stmt.paramTypes
	}

	for i := 0; i < stmt.params; i++ {
		if nullBitmap[i/8]&(1<<(i%8)) != 0 {
			params = append(params, nil)
			continue
		}

		if pos >= len(data) {
			return nil, nil, fmt.Errorf("数据不足以解析参数值")
		}

		if len(paramTypes) <= i*2 {
			return nil, nil, fmt.Errorf("参数类型信息不足")
		}

		paramType := binary.LittleEndian.Uint16(paramTypes[i*2:])
		var param interface{}
		var err error

		switch paramType {
		case 0x01: // MYSQL_TYPE_TINY
			param, err = parseTiny(data, &pos)
		case 0x02: // MYSQL_TYPE_SHORT
			param, err = parseShort(data, &pos)
		case 0x03: // MYSQL_TYPE_LONG
			param, err = parseLong(data, &pos)
		case 0x04: // MYSQL_TYPE_FLOAT
			param, err = parseFloat(data, &pos)
		case 0x05: // MYSQL_TYPE_DOUBLE
			param, err = parseDouble(data, &pos)
		case 0x07: // MYSQL_TYPE_TIMESTAMP
			param, err = parseTimestamp(data, &pos)
		case 0x0a: // MYSQL_TYPE_DATE
			param, err = parseDate(data, &pos)
		case 0x0b: // MYSQL_TYPE_TIME
			param, err = parseTime(data, &pos)
		case 0x0e: // MYSQL_TYPE_DATETIME
			param, err = parseDatetime(data, &pos)
		case 0x08: // MYSQL_TYPE_LONGLONG
			param, err = parseLongLong(data, &pos)
		case 0x0f, 0xfe: // MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VAR_STRING
			param, err = parseVarString(data, &pos)
		// 可以根据需要添加更多类型的解析
		default:
			return nil, nil, fmt.Errorf("不支持的参数类型: %d", paramType)
		}

		if err != nil {
			return nil, nil, err
		}
		params = append(params, param)
	}

	return params, newParamTypes, nil
}

func reconstructSQL(sql string, params []interface{}) string {
	parts := strings.Split(sql, "?")
	if len(parts) != len(params)+1 {
		return sql
	}

	var result strings.Builder
	for i, part := range parts[:len(parts)-1] {
		result.WriteString(part)
		result.WriteString(formatParam(params[i]))
	}
	result.WriteString(parts[len(parts)-1])
	return result.String()
}

func formatParam(param interface{}) string {
	switch v := param.(type) {
	case nil:
		return "NULL"
	case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
		return fmt.Sprintf("%d", v)
	case float32, float64:
		return fmt.Sprintf("%f", v)
	case string:
		return fmt.Sprintf("'%s'", strings.ReplaceAll(v, "'", "\\'"))
	default:
		return fmt.Sprintf("'%v'", v)
	}
}
